<?php

include_once 'database.php';
include_once 'tools.php';

class Supervisor {
    
    private $sup_id;
    private $sup_name;
    private $sup_department;
    private $sup_password;
    private $sup_available;
    
    private $_a_supervisor;
    
    public function __construct($sup_id, $sup_name = NULL, $sup_department = NULL, $sup_password = NULL, $sup_available) {
        $this->sup_id = $sup_id;
        $this->sup_name = $sup_name;
        $this->sup_department = $sup_department;
        $this->sup_password = $sup_password;
        $this->sup_available = $sup_available;
    }
    
    public function getName() {
        return $this->sup_name;
    }
    
    public function getID() {
        return $this->sup_id;
    }
    
    public function getDepartment() {
        return $this->sup_department;
    }
    
    public function getPassword() {
        return $this->sup_password;
    }
    
    public function getAvailability() {
        return $this->sup_available;
    }
    
    public static function addSupervisor($sup_id, $sup_name, $department, $sup_available) {
        
        $dbo = Database::getDBOInstance();
        $password = Tools::randomPassword();   
        
        $sql = "insert into sase_supervisor values ('$sup_id', '$sup_name', '$password', '$department', $sup_available)";

        $dbo->mysql_query($sql);
        
        //Add in to supervisor-sub-count
        $dbo->mysql_query("select * from supervisor_sub_count where sup_id = '$sup_id'");
        
        if ( mysql_num_rows($result) > 0 )
            $dbo->mysql_query("delete from supervisor_sub_count where sup_id = '$sup_id");
            
        $dbo->mysql_query("insert into supervisor_sub_count values ('$sup_id', 0)");
    }
    
    /**
     * This function will clear all the supervisors from the table
     */ 
    public static function clearSupervisors() {
        $dbo = Database::getDBOInstance();
        
        $sql = "delete from sase_supervisor";
        $dbo->mysql_query($sql);
        
        $dbo->mysql_query("delete from supervisor_sub_count");
        $dbo->mysql_query("delete from subject_sup_count");
        $dbo->mysql_query("delete from default_supervisor");
    }
    
    public static function resetSupervision() {
        $dbo->mysql_query("delete from supervises_subject");
        $dbo->mysql_query("delete from supervisor_sub_count");
        $dbo->mysql_query("delete from subject_sup_count");
    }
    
    
    
    
    
    /**
     * This function will return an Supervisor object that can be used get values
     * @param String $sup_id The ID of the supervisor
     * @return Supervisor A supervisor object
     */ 
    public static function getSupervisorObject($sup_id) {
        $dbo = Database::getDBOInstance();
        $result = $dbo->mysql_query("select * from sase_supervisor where sup_id = '$sup_id'");
        $row = mysql_fetch_assoc($result);
        
        return new Supervisor($row['sup_id'], $row['sup_name'], $row['sup_department'], $row['sup_pwd'], $row['sup_available']);
    }
    
    
    
    
    
    /**
     * Will enrol a supervisor to a subject on request. As a result will increment supervisor-subject
     * counts as well as subject supervisor counts. This method could use detectCollision() method
     * but it is though that the inclusing could reduce the flexibility of the implementation and
     * at the moment is not included.
     * 
     * @param String $subjectID Subject that the supervisor needs to be allocated
     * @param String $supervisorID Supervisor (ID) that needs to be allocated to the subject
     * 
     */ 
    public static function enrolSubject($subjectID, $supervisorID = NULL) {
        $dbo = Database::getDBOInstance();
        if ($supervisorID == NULL) $supervisorID = $this->sup_id;  
        $result = $dbo->mysql_query("insert into supervises_subject values ('$subjectID', '$supervisorID')");
        
        //Increment the count of subject-supervisor-count
        $result = $dbo->mysql_query("update subject_sup_count set sub_count = sub_count + 1 where sub_code = '$subjectID'");
        //Increment the count of the supervisor subject count
        $result = $dbo->mysql_query("select * from supervisor_sub_count where sup_id = '$supervisorID'");
        if (mysql_num_rows($result) == 0)
            $result = $dbo->mysql_query("insert into supervisor_sub_count values ('$supervisorID', 0)");
        $result = $dbo->mysql_query("update supervisor_sub_count set sup_count = sup_count + 1 where sup_id = '$supervisorID'");
    }
    
    
    
    
    /**
     * This method will check a given subject with the current set of allocations and
     * sees if there are any collisions.
     * 
     * @param String $subjectID -The ID of the subject, ex CO316
     * @param String $supervisorID -The ID of the supervisor, ex a@pdn.ac.lk
     * 
     * @return String 'exists' - Subject already selected
     * @return String 'collision' - Subject colides with already selected subject
     * @return String 'ok' - No collision
     */ 
    public static function detectCollision($subjectID, $supervisorID = NULL) {
        $dbo = Database::getDBOInstance();
        
        //Check if already selected
        $result = $dbo->mysql_query("select * from supervises_exam where sup_id = '$supervisorID and sub_code = '$subjectID'");
        if (! ( mysql_num_rows($result) == 0 ) ) return 'exists';
        
        //Get subject start time
        $result = $dbo->mysql_query("select * from sase_subject where sub_id = '$subjectID'");
        $row = mysql_fetch_assoc($result);
        $sub_day = $row['sub_day'];
        $sub_strart = $row['sub_start'];
        
        //Check for collission
        $query = "SELECT * "
                    . "FROM sase_subject AS sub, sase_supervisor AS sup, supervises_subject AS supsub "
                    . "WHERE sup.sup_id ='c@pdn.ac.lk' "
                    . "AND sup.sup_id = supsub.sup_id "
                    . "AND sub.sub_code = supsub.sub_code "
                    . "AND ( "
                        . "sub.sub_day = '$sub_day' " 
                        . "AND sub.sub_start <'$sub_start' " 
                        . "AND sub.sub_end >'$sub_end' " 
                    . ")";

        $result = $dbo->mysql_query($query);
        
        if (mysql_num_rows($result) > 0) return 'collision';
        return 'ok';
    }
    
    
    /**
     * If a supervisor needs to be removed from an allocation made by him or the system 
     * (as a default supervisor) this method should be triggered. It will removee the 
     * subject from 'Supervises_Subject' relation which defines if a supervisor supervises
     * a specific subject. Other than that it will also reduce counters for the supervisor
     * by one, and the counter for the subject (which keeps track of the number of supervisors)
     * by one to accomadate the removal.
     * 
     * If the subject is the last of the available default supervisors for the subject, 
     * removal will be disqualified and message 'last' would be returned.
     * 
     * @param String $supervisorID The supervisor that needs to be removed
     * @param String $subjectID The subject that the supervisor needs to be removed from
     * @return String 'last' Subject is the last available supervisor
     * @return String 'done' Operation successful
     * 
     */ 
    public static function dropSubject ($supervisorID = NULL, $subjectID = NULL) {
        $dbo = Database::getDBOInstance();
        
        //check if default supervisor
        $result = $dbo->mysql_query("select * from default_supervisor where sub_code = '$subjectID' and sup_id = '$supervisorID'");
        $ds = false;
        if (mysql_num_rows($result) > 0) $ds = true;
        
        //Check how many default supervisors are there
        if ($ds) {
            if ( Subject::getRemainderDefaultSupervisors($subjectID) <= 1 )
                return 'last';
        }
        
        //Now its clear to delte, if ds then there is atleast 1 left after deletion
        if ($supervisorID == NULL) $supervisorID = $this->sup_id;  
        $result = $dbo->mysql_query("delete from supervises_subject where sup_id = '$supervisorID' and sub_code = '$subjectID'");
        //echo 'here';
        //Reduce counters
        if ($result) {
            $result = $dbo->mysql_query("update subject_sup_count set sub_count = sub_count - 1 where sub_code = '$subjectID'");
            $result = $dbo->mysql_query("update supervisor_sub_count set sup_count = sup_count - 1 where sup_id = '$supervisorID'");
            $result = "done";
        }
        return $result;
    }
    
    
    
    /**
     * When a supervisor needs to be added as a default supervisor, a supervisor incharge of the
     * subject, this method needs to be triggered. It will by it self enrol the supervisor to
     * the subject.
     * 
     * @param String $subjectID The ID of the subject that the supervisor needs to be enroled to
     * @param String $supervisorID The supervisor that is to be enroled (as this is a Static function)
     * 
     */ 
    public static function enrolDefaultSupervisor($subjectID, $supervisorID = NULL) {
        $dbo = Database::getDBOInstance();
        if ($supervisorID == NULL) $supervisorID = $this->sup_id;  
        $result = $dbo->mysql_query("insert into default_supervisor (sub_code, sup_id) values ('$subjectID','$supervisorID')");
        
        Supervisor::enrolSubject($subjectID, $supervisorID);
    }
    
    /**
     * When the old and new password of a supervisor is given to this function it will
     * update the value to the new one if the given old password is correct. Return TRUE 
     * if operation was success else FALSE.
     * 
     * @param String $supervisorID Supervisor that needs to change the password
     * @param String $oldPassword Supervisors old password (should be correct to change)
     * @param String $newPassword The new password that should be set to
     * @return TRUE If operation was successful
     * @return FALSE If operation was unsuccessful
     * 
     */ 
    public static function updatePassword($supervisorID, $oldPassword, $newPassword) {
        $dbo = Database::getDBOInstance();
        
        //Check if old pwd correct
        $result = $dbo->mysql_query("select * from sase_supervisor where sup_id = '$supervisorID' and sup_pwd = '$oldPassword'");
        if (mysql_num_rows($result) == 0)
            return FALSE;
        
        //Set to new password    
        $result = $dbo->mysql_query("update sase_supervisor set sup_pwd = '$newPassword' where sup_id = '$supervisorID'");
        if ($result) return TRUE;
        return FALSE;
    }
    
    
    
    public static function updateInformation($supervisorIsup_exam_mincountD, $supervisorName, $supervisorAvailability) {
        $dbo = Database::getDBOInstance();
        
        $dbo->mysql_query("update sase_supervisor set sup_name = '$supervisorName', sup_available = $supervisorAvailability where sup_id = '$supervisorID'");
    }
    
    
    /**
     * 
     */ 
    public static function getUnallocatedSupervisors() {
        $dbo = Database::getDBOInstance();
        
        //Get how many exams a supervisor needs to complete 
        $query = "select * from general where property = 'sup_exam_mincount'";
        $result = $dbo->mysql_query($query);
        $row = mysql_fetch_assoc($result);
        $requirement = $row['value'];
        
        //Get those who haven't completed the allocation
        $query = "select ssc.sup_id from supervisor_sub_count ssc, sase_supervisor as ss where ss.sup_id = ssc.sup_id and ss.sup_available = 1 and sup_count < $requirement";
        $result = $dbo->mysql_query($query);
        
        $list = array();
        
        //Fetch result to array
        while ($row = mysql_fetch_assoc($result)) {
            $list[] = $row['sup_id'];
        }
        
        //provide with the list of supervisors who haven't completed the allocation
        return $list;
    }
    
    public static function getInconsistancy() {
        $dbo = Database::getDBOInstance();
        
        $sase_supervisors = array();
        $supervises_subject = array();
        $default_supervisor = array();
        $inconsistancy = array();
        
        $result = $dbo->mysql_query("select * from sase_supervisor");
        
        while ($row = mysql_fetch_assoc($result)) {
            $sase_supervisors[] = $row['sup_id'];
        }
        
        $result = $dbo->mysql_query("select * from supervises_subject");
        
        while ($row = mysql_fetch_assoc($result)) {
            $supervises_subject[] = $row['sup_id'];                 
        }

        $result = $dbo->mysql_query("select * from default_supervisor");
        
        while ($row = mysql_fetch_assoc($result)) {
            $default_supervisor[] = $row['sup_id']; 
        }
        
        foreach ($supervises_subject as $sub) {
            if ( array_search($sub, $sase_supervisors) === FALSE )
                $inconsistancy[] = $sub;
        }
        
        foreach ($default_supervisor as $sub) {
            if ( ( array_search($sub, $sase_supervisors)) && (array_search($sub, $inconsistancy) ) )
                $inconsistancy[] = $sub;   
        }
        
        $inconsistancy = array_unique( $inconsistancy ); 
        sort( $inconsistancy );
        
        return $inconsistancy;
    }
    
    public static function getSupervisorDetails($supID) {
        
        $dbo = Database::getDBOInstance();
        
        $result = $dbo->mysql_query("select * from sase_supervisor where sup_id = '$supID'");
        
        $row = mysql_fetch_assoc($result);
        $details = array('sup_id' => $row['sup_id'], 'sup_name' => $row['sup_name'], 'sup_department' => $row['sup_department'], 
            'sup_available' => $row['sup_available']);

        return $details;
    }
    
    /**
     * For a given supervisor id, this will return a list of subject codes
     * @param String $supID Supervisor ID
     * @return String Array $list List of subject codes allocated by the supervisor 
     */ 
    public static function getAllocation($supID){
        $dbo = Database::getDBOInstance();
        
        $result = $dbo->mysql_query("select * from supervises_subject where sup_id = '$supID' order by sub_code");
        
        $list = array();
        while ($row = mysql_fetch_assoc($result)) {
            $list[] = $row['sub_code'];
        }
        
        return $list;
    }
    
    
    public static function deleteSupervisor($supID) {
        $dbo = Database::getDBOInstance();
        
        //drop supervision
        $list = Supervisor::getAllocation($supID);
        foreach ($list as $sub) {
            Supervisor::dropSubject($supID, $sub);
        }
        //Remove from default supervisor
        $result = $dbo->mysql_query("delete from default_supervisor where sup_id = '$supID'");
        
        //Delete from sase_supervisor
        $result = $dbo->mysql_query("delete from sase_supervisor where sup_id = '$supID'");
    }
    
    public static function updateSupervisor($supID, $supDetails) {
        $dbo = Database::getDBOInstance();
        $sup_name = $supDetails['sup_name'];
        $sup_department = $supDetails['sup_department'];
        $sup_available = $supDetails['sup_available'];
        $dbo->mysql_query("update sase_supervisor set sup_name = '$sup_name', sup_department = '$sup_department', sup_available = $sup_available");
    }
}

?>